import React, { memo, useState } from "react";
import { Button, Popconfirm, message } from "antd";
import { createStyles } from "antd-style";
import { DataAction, OnError, IOuterOperatorProps } from '../typing';
import { PlusOutlined, EditOutlined, DeleteOutlined, CopyOutlined } from '@ant-design/icons';
import { withModal, mountModal } from '../../pro-hoc/withModal';
import CreateOrEdit from './CreateOrEdit';


export interface OperatorProps extends IOuterOperatorProps {
  selectedRowKeys: string[];
  selectedRows: any[];
  clearSelected: () => void;
  dataAction: DataAction;
  onError: OnError;
  doFetchList: () => void;
}

const Operator: React.FC<OperatorProps> = ({ selectedRowKeys, selectedRows, clearSelected, dataAction, onError, doFetchList, createOrEditProps, btnList }) => {
  const { styles } = useStyle();
  const [messageApi, messageContextHolder] = message.useMessage()

  const showCreateOrEditModal = (rowKey: number | string = "") => {
    const CreateOrEditModal = withModal(CreateOrEdit);
    // @ts-ignore
    mountModal(<CreateOrEditModal
      onError={onError}
      rowKey={rowKey}
      dataAction={dataAction}
      {...createOrEditProps}
      modalProps={Object.assign(createOrEditProps.modalProps || {}, {
        title: createOrEditProps.getModalTitle ? createOrEditProps.getModalTitle(rowKey) : ""
      })}
    />);
  }

  const operatorBtnList: { [index: string]: React.FC<{ onClick?: (selectedRowKeys: string[]) => void, label: string, clearSelected: () => void, isDisableFn?: (data: any[]) => boolean }> } = {
    "create": ({ onClick, label, isDisableFn }) => (
      <Button
        key="create"
        type="primary"
        icon={<PlusOutlined />}
        disabled={!!(isDisableFn && isDisableFn(selectedRows)) || selectedRowKeys.length > 0}
        onClick={onClick ? () => onClick(selectedRowKeys) : () => showCreateOrEditModal()}
      >{label || "创建"}</Button>
    ),
    "edit": ({ onClick, label, isDisableFn }) => (
      <Button
        key="edit"
        type="primary"
        icon={<EditOutlined />}
        disabled={!!(isDisableFn && isDisableFn(selectedRows)) || selectedRowKeys.length != 1}
        onClick={onClick ? () => onClick(selectedRowKeys) : () => showCreateOrEditModal(selectedRowKeys[0])}
      >{label || "编辑"}</Button>
    ),
    "delete": ({ onClick, label, clearSelected, isDisableFn }) => {
      const [loading, setLoading] = useState(false)
      const disabled = !!(isDisableFn && isDisableFn(selectedRows)) || !(selectedRowKeys.length > 0);
      const title = label || "删除";

      if (disabled) {
        return <Button type="primary" loading={loading} icon={<DeleteOutlined />} disabled={disabled} danger >{title}</Button>
      }

      return (
        <Popconfirm
          key="delete"
          title={"确定删除?"}
          onConfirm={() => {
            if (!onClick) {
              setLoading(true)
              dataAction.deleteItems(selectedRowKeys).then(() => {
                messageApi.success("删除成功", 2);
                setLoading(false);
                clearSelected()
                doFetchList();
              }).catch((e) => {
                setLoading(false)
                clearSelected()
                onError(e.msg || e.message)
              })
            } else {
              onClick(selectedRowKeys);
            }
          }}
        >
          <Button type="primary" loading={loading} icon={<DeleteOutlined />} danger disabled={disabled}>{title}</Button>
        </Popconfirm>
      )
    },
    "copy": ({ onClick, label, isDisableFn }) => (
      <Button
        key="copy"
        type="primary"
        icon={<CopyOutlined />}
        disabled={!!(isDisableFn && isDisableFn(selectedRows)) || !(selectedRowKeys.length > 0)}
        onClick={() => {
          if (!onClick) {
            dataAction.copyItems(selectedRowKeys).then(() => doFetchList()).catch((e) => onError(e.msg || e.message))
          } else {
            onClick(selectedRowKeys);
          }
        }}
      >{label ||  "复制"}</Button>
    )
  }

  if (!btnList || btnList.length == 0) return null;

  return (
    <div className={styles.operator}>
      {btnList.map(({ innerType, onClick, label, ExtendComponent, isDisableFn }, index) => {
        const Com = operatorBtnList[innerType] || ExtendComponent;
        if (!Com) return null;
        return <span className={styles.btn} key={index}>
          <Com
            onClick={onClick}
            selectedRowKeys={selectedRowKeys}
            selectedRows={selectedRows}
            doFetchList={doFetchList}
            clearSelected={clearSelected}
            isDisableFn={isDisableFn}
            label={label}
          />
        </span>;
      })}
      
      {messageContextHolder}
    </div>
  )
}

export default memo(Operator);

const useStyle = createStyles(({css}) => ({
  operator:css`
    flex-shrink: 0;
    padding-right: 5px;
  `,
  btn:css`
    margin-right: 5px;
  `
}))

